﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using TED.Model;
using TED;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using System.IO;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;
using System.Xml;

namespace TED.ViewModels
{
    public class VideoViewModel : INotifyPropertyChanged
    {
         private MediaElement MyMediaElement;
         private FrameworkElement SeekControl;
         private DispatcherTimer progressTimer;
         private TEDVideo t;
        private const string FILE_NAME = "playlist.xml";

        public VideoViewModel()
        {
            // Set the command property
            MediaOpenedCommand = new DelegateCommand(MediaOpened, CanMediaOpened);
            PlayVideoCommand = new DelegateCommand(PlayVideo, CanPlayVideo);
            StopVideoCommand = new DelegateCommand(StopVideo, CanStopVideo);
            PauseVideoCommand = new DelegateCommand(PauseVideo, CanPauseVideo);
            SetSeekControlCommand = new DelegateCommand(SetSeekControl, CanSetSeekControl);
            SetVideoCommand = new DelegateCommand(SetVideo, CanSetVideo);

            t = new TEDVideo();
            
            // Call the Model to get the collection of TEDVideo
            this.SilverlightVideoList = new ObservableCollection<TEDVideo>();
            this.GetPlaylist();
        }
        
        // Commands

        #region MediaOpenedCommand
        public ICommand MediaOpenedCommand { get; set; }
        public void MediaOpened(object param)
        {
            // Play Video
            MediaElement parmMediaElement = (MediaElement)param;
            MyMediaElement = parmMediaElement;

            this.progressTimer = new DispatcherTimer();
            this.progressTimer.Interval = TimeSpan.FromSeconds(1);
            this.progressTimer.Tick += new EventHandler(this.ProgressTimer_Tick);

            SetCurrentPosition();

            // Play the video
            PlayVideo(null);
        }

        private bool CanMediaOpened(object param)
        {
            return true;
        }
        #endregion

        #region SetSeekControlCommand
        public ICommand SetSeekControlCommand { get; set; }
        public void SetSeekControl(object param)
        {
            // Hook Events into the Seek Control
            SeekControl = (FrameworkElement)param;
            SeekControl.MouseLeftButtonDown += new MouseButtonEventHandler(SeekControl_MouseLeftButtonDown);
        }

        private bool CanSetSeekControl(object param)
        {
            return true;
        }

        private void SeekControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            double position = e.GetPosition(SeekControl).X;
            double percent = position / SeekControl.ActualWidth;
            Seek(percent);
        }

        private void Seek(double percentComplete)
        {
            TimeSpan duration = MyMediaElement.NaturalDuration.TimeSpan;
            int newPosition = (int)(duration.TotalSeconds * percentComplete);
            MyMediaElement.Position = new TimeSpan(0, 0, newPosition);
            SetCurrentPosition();
        }
        #endregion

        #region PlayVideoCommand
        public ICommand PlayVideoCommand { get; set; }
        public void PlayVideo(object param)
        {
            // Play Video
            MyMediaElement.Play();
            progressTimer.Start();
        }

        private bool CanPlayVideo(object param)
        {
            bool CanPlay = false;
            // only allow Video to Play if it is not already Playing
            if (MyMediaElement != null)
            {
                if (MyMediaElement.CurrentState != MediaElementState.Playing)
                {
                    CanPlay = true;
                }
            }
            return CanPlay;
        }
        #endregion

        #region StopVideoCommand
        public ICommand StopVideoCommand { get; set; }
        public void StopVideo(object param)
        {
            // Stop Video
            MyMediaElement.Stop();
            progressTimer.Stop();
            SetCurrentPosition();
        }

        private bool CanStopVideo(object param)
        {
            bool CanStop = false;

            if (MyMediaElement != null)
            {
                CanStop = true;
            }

            return CanStop;
        }
        #endregion

        #region PauseVideoCommand
        public ICommand PauseVideoCommand { get; set; }
        public void PauseVideo(object param)
        {
            // We only want to Pause if the media is Playing
            if (MyMediaElement.CurrentState == MediaElementState.Playing)
            {
                // If we can Pause the Video, Pause it
                if (MyMediaElement.CanPause)
                {
                    // Pause Video
                    MyMediaElement.Pause();
                }
                else
                {
                    // We can't pause the Video so Stop it
                    MyMediaElement.Stop();
                }

                if (progressTimer.IsEnabled)
                {
                    progressTimer.Stop();
                }
            }
            else
            {
                // The Media is not Playing so we are Paused
                // Play Video
                MyMediaElement.Play();
                progressTimer.Start();
            }

        }

        private bool CanPauseVideo(object param)
        {
            bool CanPause = false;

            if (MyMediaElement != null)
            {
                // Only allow this Command if paused or Playing
                if ((MyMediaElement.CurrentState == MediaElementState.Paused)
                    || (MyMediaElement.CurrentState == MediaElementState.Playing))
                {
                    CanPause = true;
                }
            }

            return CanPause;
        }
        #endregion

        #region SetVideoCommand
        public ICommand SetVideoCommand { get; set; }
        public void SetVideo(object param)
        {
            // Set Video
            string tmpSelectedVideo = string.Format(@"{0}", (param as TEDVideo).VideoUrl);
            SelectedVideoProperty = new Uri(tmpSelectedVideo, UriKind.RelativeOrAbsolute);

            // Stop Progress Timer
            if (progressTimer != null)
            {
                if (progressTimer.IsEnabled)
                {
                    progressTimer.Stop();
                }
            }
        }

        private bool CanSetVideo(object param)
        {
            // only set video if the parameter is not null
            return (param != null);
        }
        #endregion

        // Events

        #region Time display
        private void ProgressTimer_Tick(object sender, EventArgs e)
        {
            SetCurrentPosition();
        }

        private void SetCurrentPosition()
        {
            // If the Media play is complete stop the media
            if (CurrentPositionProperty > 0)
            {
                if (CurrentPositionProperty >= TotalDurationProperty)
                {
                    CurrentPositionProperty = 0;
                    StopVideo(null);
                }
            }

            // Update the time text e.g. 01:50 / 03:30
            CurrentProgressProperty = string.Format(
                "{0}:{1} / {2}:{3}",
                Math.Floor(MyMediaElement.Position.TotalMinutes).ToString("00"),
                MyMediaElement.Position.Seconds.ToString("00"),
                Math.Floor(MyMediaElement.NaturalDuration.TimeSpan.TotalMinutes).ToString("00"),
                MyMediaElement.NaturalDuration.TimeSpan.Seconds.ToString("00"));

            CurrentPositionProperty = MyMediaElement.Position.TotalSeconds;
            TotalDurationProperty = MyMediaElement.NaturalDuration.TimeSpan.TotalSeconds;
            MediaBufferingProperty = (MyMediaElement.CurrentState == MediaElementState.Buffering);
            MediaBufferingTimeProperty = String.Format("Buffering {0} %", (MyMediaElement.BufferingProgress * 100).ToString("##"));
        }
        #endregion

        // Manage Playlist
        #region GetPlaylist
        public void GetPlaylist()
        {
            //Read from the Isolated Storage
            try
            {
                using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile(FILE_NAME, FileMode.Open))
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<TEDVideo>));
                        SilverlightVideoList = (ObservableCollection<TEDVideo>)serializer.Deserialize(stream);
                    }
                    SetVideo(SilverlightVideoList[0]);
                    SelectedVideoInListProperty = 0;
                }
            }
            catch
            {
                //add some code here
            }
        }
        #endregion

        #region AddVideoToPlaylist
        public void AddVideoToPlaylist(TEDVideo t)
        {
            GetPlaylist();
            SilverlightVideoList.Add(t);
            SavePlaylistToStorage();
        }

        public void AddDefaultWMVVideoToPlaylist()
        {
            
            GetPlaylist();
            SilverlightVideoList.Add(new TEDVideo { VideoUrl = @"http://smf.vertigo.com/videos/wildlife.wmv", Title = "Default video to test", Author = "", ImageUrl = null , ViewUrl=@"http://smf.vertigo.com/videos/wildlife.wmv"});
            SavePlaylistToStorage();
        }
        
        private void SavePlaylistToStorage()
        {
            // Write to the Isolated Storage
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            xmlWriterSettings.Indent = true;

            using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile(FILE_NAME, FileMode.Create))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(ObservableCollection<TEDVideo>));
                    using (XmlWriter xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
                    {
                        serializer.Serialize(xmlWriter, SilverlightVideoList);
                    }
                }
            }
        }
        #endregion

        #region RemoveVideoFromPlaylist
        public bool RemoveVideoFromPlaylist(string viewUrl)
        {
            this.GetPlaylist();
            try
            {
                for (int i = 0; i < SilverlightVideoList.Count; ++i)
                {
                    if ((SilverlightVideoList[i].ViewUrl.Equals(viewUrl)) == true)
                    {
                        SilverlightVideoList.RemoveAt(i);
                        --i;
                    }
                }
       
                //Update playlist
                SavePlaylistToStorage();
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                return false;
            }
        }

        public void RemoveAllVideosFromPlaylist()
        {
            using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                myIsolatedStorage.DeleteFile(FILE_NAME);
                SilverlightVideoList.Clear();
            }
        }
        #endregion

        private void GetListOfTEDVideo()
        {
            SilverlightVideoList = new ObservableCollection<TEDVideo>();

            SilverlightVideoList.Add(new TEDVideo { Title = "RIAServices", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule2-SL4LOB_02_01_RIAServices/Silverlight4-SL4BusinessModule2-SL4LOB_02_01_RIAServices_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title= "Introduction", VideoUrl = @"http://video.ted.com/talks/dynamic/DavidMcCandless_2010G-medium.flv" });
            

            /*
            SilverlightVideoList.Add(new TEDVideo { Title = "Editing Entities", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule2-SL4LOB_02_02_EditingEntities/Silverlight4-SL4BusinessModule2-SL4LOB_02_02_EditingEntities_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Showing Events", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule2-SL4LOB_02_03_ShowingEvents/Silverlight4-SL4BusinessModule2-SL4LOB_02_03_ShowingEvents_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Authentication", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule3-SL4LOB_03_01_Authentication/Silverlight4-SL4BusinessModule3-SL4LOB_03_01_Authentication_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "MVVM", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule3-SL4LOB_03_02_MVVM/Silverlight4-SL4BusinessModule3-SL4LOB_03_02_MVVM_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Validation", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule3-SL4LOB_03_03_Validation/Silverlight4-SL4BusinessModule3-SL4LOB_03_03_Validation_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "ImplicitStyles", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule3-SL4LOB_03_04_ImplicitStyles/Silverlight4-SL4BusinessModule3-SL4LOB_03_04_ImplicitStyles_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "RichTextBox", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule3-SL4LOB_03_05_RichTextBox/Silverlight4-SL4BusinessModule3-SL4LOB_03_05_RichTextBox_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Webcam", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule4-SL4LOB_04_01_Webcam/Silverlight4-SL4BusinessModule4-SL4LOB_04_01_Webcam_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Drop", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule4-SL4LOB_04_02_Drop/Silverlight4-SL4BusinessModule4-SL4LOB_04_02_Drop_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Grouping", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule5-SL4LOB_05_01_Grouping/Silverlight4-SL4BusinessModule5-SL4LOB_05_01_Grouping_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "FluidUI", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule5-SL4LOB_05_02_FluidUI/Silverlight4-SL4BusinessModule5-SL4LOB_05_02_FluidUI_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "RightMouseClick", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule5-SL4LOB_05_03_RightMouseClick/Silverlight4-SL4BusinessModule5-SL4LOB_05_03_RightMouseClick_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Printing", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule6-SL4LOB_06_01_Printing/Silverlight4-SL4BusinessModule6-SL4LOB_06_01_Printing_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "MultipagePrinting", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule6-SL4LOB_06_02_MultipagePrinting/Silverlight4-SL4BusinessModule6-SL4LOB_06_02_MultipagePrinting_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "OOB", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule7-SL4LOB_07_01_OOB/Silverlight4-SL4BusinessModule7-SL4LOB_07_01_OOB_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Toasts", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule7-SL4LOB_07_02_Toasts/Silverlight4-SL4BusinessModule7-SL4LOB_07_02_Toasts_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Window Placement", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule7-SL4LOB_07_03_WindowPlacement/Silverlight4-SL4BusinessModule7-SL4LOB_07_03_WindowPlacement_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Elevated Trust", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule7-SL4LOB_07_04_ElevatedTrust/Silverlight4-SL4BusinessModule7-SL4LOB_07_04_ElevatedTrust_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Custom Chrome", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule8-SL4LOB_08_01_CustomChrome/Silverlight4-SL4BusinessModule8-SL4LOB_08_01_CustomChrome_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Window Closing Event", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule8-SL4LOB_08_02_WindowClosingEvent/Silverlight4-SL4BusinessModule8-SL4LOB_08_02_WindowClosingEvent_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "OOB Silent Install", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule8-SL4LOB_08_03_OOBSilentInstall/Silverlight4-SL4BusinessModule8-SL4LOB_08_03_OOBSilentInstall_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "Xap Signing", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule8-SL4LOB_08_04_XapSigning/Silverlight4-SL4BusinessModule8-SL4LOB_08_04_XapSigning_kit.wmv" });
            SilverlightVideoList.Add(new TEDVideo { Title = "MEF", VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule8-SL4LOB_08_05_MEF/Silverlight4-SL4BusinessModule8-SL4LOB_08_05_MEF_kit.wmv" });
            */
            
             
        }

        // Properties

        #region SelectedVideoProperty
        private Uri _SelectedVideoProperty;
        public Uri SelectedVideoProperty
        {
            get
            {
                return this._SelectedVideoProperty;
            }
            set
            {
                this._SelectedVideoProperty = value;
                this.NotifyPropertyChanged("SelectedVideoProperty");
            }
        }
        #endregion

        #region CurrentProgressProperty
        private string _CurrentProgressProperty;
        public string CurrentProgressProperty
        {
            get
            {
                return this._CurrentProgressProperty;
            }
            set
            {
                this._CurrentProgressProperty = value;
                this.NotifyPropertyChanged("CurrentProgressProperty");
            }
        }
        #endregion

        #region TotalDurationProperty
        private double _TotalDurationProperty;
        public double TotalDurationProperty
        {
            get
            {
                return this._TotalDurationProperty;
            }
            set
            {
                this._TotalDurationProperty = value;
                this.NotifyPropertyChanged("TotalDurationProperty");
            }
        }
        #endregion

        #region CurrentPositionProperty
        private double _CurrentPositionProperty;
        public double CurrentPositionProperty
        {
            get
            {
                return this._CurrentPositionProperty;
            }
            set
            {
                this._CurrentPositionProperty = value;
                this.NotifyPropertyChanged("CurrentPositionProperty");
            }
        }
        #endregion

        #region SelectedVideoInListProperty
        private int _SelectedVideoInListProperty = -1;
        public int SelectedVideoInListProperty
        {
            get
            {
                return this._SelectedVideoInListProperty;
            }
            set
            {
                this._SelectedVideoInListProperty = value;
                this.NotifyPropertyChanged("SelectedVideoInListProperty");
            }
        }
        #endregion

        #region MediaBufferingProperty
        private bool _MediaBufferingProperty;
        public bool MediaBufferingProperty
        {
            get
            {
                return this._MediaBufferingProperty;
            }
            set
            {
                this._MediaBufferingProperty = value;
                this.NotifyPropertyChanged("MediaBufferingProperty");
            }
        }
        #endregion

        #region MediaBufferingTimeProperty
        private string _MediaBufferingTimeProperty;
        public string MediaBufferingTimeProperty
        {
            get
            {
                return this._MediaBufferingTimeProperty;
            }
            set
            {
                this._MediaBufferingTimeProperty = value;
                this.NotifyPropertyChanged("MediaBufferingTimeProperty");
            }
        }
        #endregion

        // Parse TED video page to get INDIRECT link for *.mp4 video

        #region ParseTEDVideo
        /// <summary>
        /// Parse TED Video to get a link to download mp4 file
        /// </summary>
        /// <param name="viewUrl"></param>
        public void ParseTEDVideoPage(TEDVideo t)
        {
            this.t = t;
            WebClient c = new WebClient();
            string TEDUrl = "http://www.ted.com/talks/" + t.VideoUrl;
            c.DownloadStringAsync(new Uri(TEDUrl));
            c.DownloadStringCompleted += new DownloadStringCompletedEventHandler(c_DownloadStringCompleted);
        }

        /// <summary>
        /// Handle html that is returned from TED website
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void c_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            lock (this)
            {
                string responseString = e.Result;

                getVideoUrl(responseString);
            }
        }

        /// <summary>
        /// Parse website to get INDIRECT url for mp4 video
        /// </summary>
        /// <param name="viewUrl"></param>
        /// <returns></returns>
        private void getVideoUrl(String responseString)
        {
         //   string regexLinkPattern = @"<input.*?vu=(?<VideoUrl>.*?)(flv).*?>";
            string regexLinkPattern = @"<dt><a.*?href=[""'](?<VideoUrl>.*?)[""'].*?>.*?(Download).(video).(to).(desktop).*?</a></dt>";
            MatchCollection hyperlinkMatches = Regex.Matches(responseString, regexLinkPattern);


            if (hyperlinkMatches.Count > 0)
            {
                string VideoUrl = "http://www.ted.com/" + hyperlinkMatches[0].Groups["VideoUrl"].Value;
                this.GetMp4Link(VideoUrl);
            }

            //string VideoUrl = @"http://ecn.channel9.msdn.com/o9/learn/TEDVideo/Silverlight4-SL4BusinessModule2-SL4LOB_02_02_EditingEntities/Silverlight4-SL4BusinessModule2-SL4LOB_02_02_EditingEntities_kit.wmv";            
        }

        #endregion

        // Get DIRECT link for *.mp4 video

        #region Get link for *.mp4 video
        /// <summary>
        /// Request header of link to download *.mp4
        /// </summary>
        /// <param name="mp4Link"></param>
        private void GetMp4Link(string mp4Link)
        {
            try
            {
                String TEDUrl = mp4Link;
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(TEDUrl);
                webRequest.Method = "HEAD";
                

                //Start the request
                IAsyncResult token = webRequest.BeginGetResponse(new AsyncCallback(GetMp4LinkCallBack), webRequest);

            }
            catch (Exception e)
            {
                string msg = "Error: " + e.Message + ";" + e.ToString();
                MessageBox.Show(msg);
            }
            

        }

        /// <summary>
        /// Return a direct link to *.mp4 file
        /// </summary>
        /// <param name="aysnchronousResult">The asynchronous result object</param>
        private void GetMp4LinkCallBack(IAsyncResult asysnchronousResult)
        {
            HttpWebRequest webRequest = (HttpWebRequest)asysnchronousResult.AsyncState;

            //Get web response and
            WebResponse webResponse = ((HttpWebRequest)asysnchronousResult.AsyncState).EndGetResponse(asysnchronousResult);

            String mp4DirectLink = webResponse.ResponseUri.ToString();
            webResponse.Close();

            System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    t.VideoUrl = mp4DirectLink;
                    AddVideoToPlaylist(t);
                    this.NotifyPropertyChanged("SilverlightVideoList");
                });
        }

        #endregion

        // Collections

        #region SilverlightVideoList
        private ObservableCollection<TEDVideo> _SilverlightVideoList;
        public ObservableCollection<TEDVideo> SilverlightVideoList
        {
            get { return _SilverlightVideoList; }
            private set
            {
                if (SilverlightVideoList == value)
                {
                    return;
                }

                _SilverlightVideoList = value;
                this.NotifyPropertyChanged("SilverlightVideoList");
            }
        }
        #endregion

        // Utility

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
    
    }
}
